package persistencia;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import dominio.laberinto.Casillero;
import dominio.laberinto.ICasillero;
import dominio.laberinto.ILaberintoRepository;
import dominio.laberinto.Laberinto;

public class XMLLaberintoRepository implements ILaberintoRepository {

	private String path;
	private int iteracion;
	private XMLCasilleroRepository casilleroRepository; 
	
	public XMLLaberintoRepository(String path) {
		this.path = path;
		this.iteracion = 1;
		this.casilleroRepository = new XMLCasilleroRepository(); 
	}

	@Override
	public Laberinto cargar() {
		SAXReader reader = new SAXReader();
		try {
			Document document = reader.read(this.path);
			Element elemRaiz = document.getRootElement();
			this.casilleroRepository.setElemRaiz(elemRaiz);
			return this.cargar(elemRaiz);
		} catch (DocumentException ex) {
			throw new RuntimeException();
		}
	}
	
	private Laberinto cargar(Element elemRaiz) {
		Laberinto laberinto = Laberinto.getInstance();
		
		int anchoLaberinto = Integer.parseInt(elemRaiz.attributeValue("ancho"));
		int altoLaberinto = Integer.parseInt(elemRaiz.attributeValue("alto"));
		int anchoCasillero = Integer.parseInt(elemRaiz.attributeValue("nodoAncho"));
		int altoCasillero = Integer.parseInt(elemRaiz.attributeValue("nodoAlto"));
		
		laberinto.setAncho(anchoLaberinto);
		laberinto.setAlto(altoLaberinto);
		laberinto.setAnchoCasillero(anchoCasillero);
		laberinto.setAltoCasillero(altoCasillero);
		
		List<ICasillero> casilleros = this.casilleroRepository.listar();
		laberinto.setMisCasilleros(casilleros);

		String inicioPacman = elemRaiz.attributeValue("inicioPacman");
		String inicioFantasmas = elemRaiz.attributeValue("inicioFantasmas");		
		
		ICasillero casilleroInicioPacman = this.casilleroRepository.cargar(inicioPacman);
		ICasillero casilleroInicioFantasmas = this.casilleroRepository.cargar(inicioFantasmas);
	
		laberinto.setInicioPacman(casilleroInicioPacman);
		laberinto.setInicioFantasmas(casilleroInicioFantasmas);
		
		return laberinto;
	}

	@Override
	public void guardar(Laberinto laberinto) {
		Document doc = DocumentHelper.createDocument();
		doc.add(this.salvar(laberinto));
		try {
			String nombreArch= this.path.substring(0,this.path.lastIndexOf("."));
			FileWriter writer = new FileWriter(nombreArch +"Tick"+ this.iteracion + ".xml");
			doc.write(writer);
			writer.close();
		} catch (IOException e) {
			throw new RuntimeException();
		}
		this.iteracion++;
	}

	private Element salvar(Laberinto laberinto) {
		Element elemLaberinto = DocumentHelper.createElement("laberinto");
		
		Attribute ancho = DocumentHelper.createAttribute(elemLaberinto, "ancho", String.valueOf(laberinto.getAncho()));
		Attribute alto = DocumentHelper.createAttribute(elemLaberinto, "alto", String.valueOf(laberinto.getAlto()));
		Attribute anchoCasillero = DocumentHelper.createAttribute(elemLaberinto, "nodoAncho", String.valueOf(laberinto.getAnchoCasillero()));
		Attribute altoCasillero = DocumentHelper.createAttribute(elemLaberinto, "nodoAlto", String.valueOf(laberinto.getAltoCasillero()));
		Attribute inicioPacman = DocumentHelper.createAttribute(elemLaberinto, "inicioPacman", String.valueOf(laberinto.getInicioPacman().getId()));
		Attribute inicioFantasmas = DocumentHelper.createAttribute(elemLaberinto, "inicioFantasmas", String.valueOf(laberinto.getInicioFantasmas().getId()));
		
		this.casilleroRepository.setElemRaiz(elemLaberinto);
		for (ICasillero casillero : laberinto.getMisCasilleros()) {
			this.casilleroRepository.guardar(casillero);
		}
		
		elemLaberinto.add(ancho);
		elemLaberinto.add(alto);
		elemLaberinto.add(anchoCasillero);
		elemLaberinto.add(altoCasillero);
		elemLaberinto.add(inicioPacman);
		elemLaberinto.add(inicioFantasmas);
		
		return elemLaberinto;
	}

}
